#[derive(FromForm)]
struct CopywriteOrderGet {
    id: usize
}

#[post("/library/get_copywrite_order", data = "<form>")]
fn get_copywrite_order(form: Form<CopywriteOrderGet>, cookies: Cookies, state: State<MySqlDriver>) -> String {
    let user_info: UserInfo = get_cookies(&cookies);
    if user_info.id == 0 {
        return "fail:您未登录，请先登录".to_string();
    }

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        return "fail:无法建立数据库连接".to_string();
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        return "fail:无法获取数据库连接".to_string();
    }
    let mut sql: String = format!("SELECT COUNT(`id`) AS `count` FROM `copywrite_order` WHERE `id` = {}", form.id);
    let row: Row = conn.query_first(sql.clone()).unwrap().unwrap();
    let count: usize = from_row(row);
    if count == 0 {
        return "fail:该单子已被抢，请抢别的单子".to_string();
    }

    sql = format!("SELECT COUNT(`id`) AS `count` FROM `copywrite_order` WHERE `status` = 1 AND `get_user_id` = {}", user_info.id);
    let row: Row = conn.query_first(sql.clone()).unwrap().unwrap();
    let count: usize = from_row(row);
    if count >= 3 {
        return "fail:已接3个单，无法再接新单了".to_string();
    }

    let now: SystemTime = SystemTime::now();
    let since_epoch_res = now.duration_since(UNIX_EPOCH);
    let since_epoch: Duration;
    if let Ok(d) = since_epoch_res {
        since_epoch = d;
    } else {
        return "fail:时间戳获取失败".to_string();
    }
    let secs = since_epoch.as_secs();
    sql = format!("UPDATE `copywrite_order` SET `get_user_id` = :get_user_id, `status` = 1, `update_datetime` = :update_datetime WHERE `id` = :id");
    let _ = conn.exec_drop(sql.as_str(), params![
        "get_user_id" => user_info.id,
        "update_datetime" => secs,
        "id" => form.id
    ]);
    return "success:".to_string();
}

#[get("/copywrite_list", rank = 3)]
fn copywrite_list_empty(cookies: Cookies, state: State<MySqlDriver>) -> Response<'static> {
    let mut res = Response::new();
    res.set_header(ContentType::HTML);

    // mod_id: String, 
    // mod_menu_open: String, 
    // sub_mod_id: String, 
    // page_title: String, 
    // title: String
    let header: String = get_header(
        "order-mod".to_string(), 
        "order-mod-menu-open".to_string(), 
        "copywrite-order-list".to_string(),
        "用户后台 - 文案订单列表".to_string(), 
        "文案订单列表".to_string(), &cookies,
        &state);

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        res.set_sized_body(Cursor::new("无法建立数据库连接".to_string()));
        return res;
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        res.set_sized_body(Cursor::new("无法获取数据库连接".to_string()));
        return res;
    }
    let sql: String = "SELECT `type` FROM `topic` ORDER BY `id` ASC".to_string();
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut type_only_list: Vec<String> = Vec::new();
    let mut type_button_list: String = String::new();
    for row in rows {
        let r: String = from_row::<String>(row);
        let ho_t: HoString = HoString::copy_string(r);
        let type_list: Vec<HoString> = ho_t.split_bytes(",".as_bytes());
        for j in 0..type_list.len() {
            if let Some(type_str) = type_list.get(j) {
                if type_str.compare_str("") {
                    continue;
                } else if type_only_list.contains(&type_str.to_string()) == false {
                    type_only_list.push(type_str.clone().to_string());
                    type_button_list.push_str(
                        format!("<button class=\"dropdown-item\" \
                                type=\"button\" onclick=\"set_type('{}')\">{}</button>", 
                                type_str.to_str(), type_str.to_str()).as_str());
                }
            }
        }
    }

    let mut src_vec: Vec<&[u8]> = Vec::new();
    let mut replace_vec: Vec<&[u8]> = Vec::new();

    src_vec.push("{header}".as_bytes());
    src_vec.push("{base_url}".as_bytes());
    src_vec.push("{type_buttons}".as_bytes());
    src_vec.push("{footer}".as_bytes());
    replace_vec.push(header.as_bytes());
    replace_vec.push(state.base_url.as_bytes());
    replace_vec.push(type_button_list.as_bytes());
    let footer_string: String = get_footer();
    replace_vec.push(footer_string.as_bytes());

    let mut page_str: HoString = HoFile::read_file_bytes("web/copywrite_list_empty.html");
    page_str = page_str.replace_bytes_vec(src_vec, replace_vec);
    let html: String = page_str.to_str().to_string().to_owned();
    res.set_sized_body(Cursor::new(html));
    return res;
}

struct TypeMember {
    group_id: usize,
    publish_count: usize,
    number: String,
    v: Vec<String>
}

#[allow(unused_assignments)]
#[get("/copywrite_list?<p>&<topic_type>", rank = 2)]
fn copywrite_list_2(p: usize, topic_type: String, cookies: Cookies, state: State<MySqlDriver>) -> Response<'static> {
    let mut res = Response::new();
    res.set_header(ContentType::HTML);

    // mod_id: String, 
    // mod_menu_open: String, 
    // sub_mod_id: String, 
    // page_title: String, 
    // title: String
    let header: String = get_header(
        "order-mod".to_string(), 
        "order-mod-menu-open".to_string(), 
        "copywrite-order-list".to_string(),
        "用户后台 - 文案订单列表".to_string(), 
        "文案订单列表".to_string(), &cookies,
        &state);

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        res.set_sized_body(Cursor::new("无法建立数据库连接".to_string()));
        return res;
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        res.set_sized_body(Cursor::new("无法获取数据库连接".to_string()));
        return res;
    }

    let mut sql: String = "SELECT `type` FROM `topic` ORDER BY `id` ASC".to_string();
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut type_only_list: Vec<String> = Vec::new();
    let mut type_button_list: String = String::new();
    for row in rows {
        let r: String = from_row::<String>(row);
        let ho_t: HoString = HoString::copy_string(r);
        let type_list: Vec<HoString> = ho_t.split_bytes(",".as_bytes());
        for j in 0..type_list.len() {
            if let Some(type_str) = type_list.get(j) {
                if type_str.compare_str("") {
                    continue;
                } else if type_only_list.contains(&type_str.to_string()) == false {
                    type_only_list.push(type_str.clone().to_string());
                    type_button_list.push_str(
                        format!("<button class=\"dropdown-item\" \
                                type=\"button\" onclick=\"set_type('{}')\">{}</button>", 
                                type_str.to_str(), type_str.to_str()).as_str());
                }
            }
        }
    }

    let mut skip_number: usize = 0;
    sql = format!("SELECT COUNT(`co`.`id`) AS `count` \
                  FROM `copywrite_order` AS `co` \
                  INNER JOIN `topic` AS `t` ON `t`.`id` = `co`.`topic_id` \
                  WHERE `co`.`status` = 0 AND `t`.`type` LIKE '%,{},%' AND `group_id` = 0 \
                  ORDER BY `co`.`id` DESC", topic_type.as_str());
    let rows: Option<Row> = conn.query_first(sql.clone()).unwrap();
    let count: usize;
    if let Some(row) = rows {
        let count_str: String = from_row::<String>(row);
        count = count_str.parse::<usize>().unwrap();
    } else {
        res.set_sized_body(Cursor::new("无法查询订单数量".to_string()));
        return res;
    }
    let max_page: usize = ceil((count / 10) as f64, 0) as usize;
    skip_number = (p - 1) * 10;

    sql = "SELECT `id`, `number` FROM `tag_group`".to_string();
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut type_member_list: Vec<TypeMember> = Vec::new();
    for row in rows {
        let (id_str, number): (String, String) = from_row(row);
        let id: usize = id_str.parse::<usize>().unwrap();
        sql = format!("SELECT COUNT(`id`) AS `count` \
                      FROM `clip_order` \
                      WHERE `group_id` = {} AND \
                            `status` = 4", id.to_string().as_str());
        let row2: Row = conn.query_first(sql.clone()).unwrap().unwrap();
        let count: usize = from_row::<usize>(row2);
        let type_member: TypeMember = TypeMember {
            group_id: id,
            publish_count: count,
            number: number,
            v: Vec::new()
        };
        type_member_list.push(type_member);
    }
    let type_member_count: usize = type_member_list.len();
    for i in 0..type_member_count - 1 {
        for j in 0..type_member_count - i - 1 {
            if type_member_list.get(j).unwrap().publish_count > type_member_list.get(j + 1).unwrap().publish_count {
                type_member_list.swap(j, j + 1);
            }
        }
    }

    for i in 0..type_member_list.len() {
        sql = format!("SELECT `t`.`movie_name` AS `v` \
                      FROM `topic` AS `t` \
                      WHERE `t`.`type` LIKE '%,{},%'", topic_type.as_str());
        let mut topic_list: Vec<String> = Vec::new();
        let topic_rows: Vec<Row> = conn.query(sql.clone()).unwrap();
        for row in topic_rows {
            let v: String = row.get("v").unwrap();
            if topic_list.contains(&v) == false {
                type_member_list[i].v.push(v.clone());
                topic_list.push(v.clone());
            }
        }
    }
    let mut type_member_str: String = String::new();
    for line in type_member_list {
        for v in line.v {
            type_member_str.push_str(format!("<button class=\"dropdown-item\" \
                                             type=\"button\" \
                                             onclick=\"set_topic({}, '{}', '{}')\">{}-{}\
                                             </button>", line.group_id, line.number, v.as_str(), line.number, v.as_str()).as_str());
        }
    }

    sql = format!("SELECT `co`.`id`, `t`.`movie_name` AS `topic_name`, `t`.`bt_file`, `co`.`requirement` FROM `copywrite_order` AS `co` INNER JOIN `topic` AS `t` ON `t`.`id` = `co`.`topic_id` WHERE `co`.`status` = 0 AND `t`.`type` LIKE '%,{},%' ORDER BY `co`.`id` DESC LIMIT {}, 10", topic_type.as_str(), skip_number);
    let table_rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut tr: String = String::new();
    for row in table_rows {
        let (row_id, topic_name, bt_file, requirement): (String, String, String, String) = from_row(row);
        let files: HoString = HoString::copy_string(bt_file);
        let file_list: Vec<HoString> = files.split_bytes(b"|");
        let bt_file: String = file_list.get(0).unwrap().to_string();

        let base_url: &str = state.base_url.as_str();
        tr.push_str(format!("<tr>\
                        <th scope=\"row\">{}</th>\
                        <td>{}</td>\
                        <td>{}</td>\
                        <td><a target=\"_blank\" href=\"{}uploads/bt_file/{}\">下载</a></td>\
                        <td>\
                            <a class=\"btn btn-primary\" target=\"_blank\" href=\"{}copywrite_edit?id={}\">查看</a>\
                            <button class=\"btn btn-success\" onclick=\"get_order({})\">接单</button>\
                        </td>\
                    </tr>", row_id.as_str(), topic_name.as_str(), requirement.as_str(), base_url, bt_file.as_str(), base_url, row_id.as_str(), row_id.as_str()).as_str());
    }

    let mut is_prev_disabled: String = String::new();
    let mut is_next_disabled: String = String::new();
    if p <= 1 {
        is_prev_disabled.push_str(" disabled");
    }
    if p >= max_page {
        is_next_disabled.push_str(" disabled");
    }
    let mut nav: String = format!("<nav>\
                            <ul class=\"pagination justify-content-center\">\
                                <li class=\"page-item{}\">\
                                  <a class=\"page-link\" href=\"copywrite_list.php?p={}&topic_type={}\" aria-label=\"Previous\">\
                                      <span aria-hidden=\"true\">&laquo;</span>\
                                  </a>\
                                </li>", is_prev_disabled.as_str(), (p - 1).to_string().as_str(), topic_type.as_str());
    for i in 1..=max_page {
        if p == i {
            nav.push_str(format!("<li class=\"page-item active\"><a class=\"page-link\" href=\"javascript:void(0);\">{}</a></li>", i).as_str());
        } else {
            nav.push_str(format!("<li class=\"page-item\"><a class=\"page-link\" href=\"copywrite_list.php?p={}&topic_type={}\">{}</a></li>", i, topic_type.as_str(), i).as_str());
        }
    }
    nav.push_str(format!("<li class=\"page-item{}\">\
                            <a class=\"page-link\" href=\"copywrite_list.php?p={}&topic_type={}\" aria-label=\"Next\">\
                                <span aria-hidden=\"true\">&raquo;</span>\
                            </a>\
                          </li>\
                      </ul>\
                    </nav>", is_next_disabled.as_str(), (p + 1).to_string().as_str(), topic_type.as_str()).as_str());

    let mut src_vec: Vec<&[u8]> = Vec::new();
    let mut replace_vec: Vec<&[u8]> = Vec::new();

    let user_info: UserInfo = get_cookies(&cookies);
    let uid: usize = user_info.id;

    src_vec.push("{header}".as_bytes());
    src_vec.push("{base_url}".as_bytes());
    src_vec.push("{skip_number}".as_bytes());
    src_vec.push("{type}".as_bytes());
    src_vec.push("{type_buttons}".as_bytes());
    src_vec.push("{topic_buttons}".as_bytes());
    src_vec.push("{tr}".as_bytes());
    src_vec.push("{nav}".as_bytes());
    src_vec.push("{uid}".as_bytes());
    src_vec.push("{footer}".as_bytes());
    replace_vec.push(header.as_bytes());
    replace_vec.push(state.base_url.as_bytes());
    let skip_number_str: String = skip_number.to_string();
    replace_vec.push(skip_number_str.as_bytes());
    replace_vec.push(topic_type.as_bytes());
    replace_vec.push(type_button_list.as_bytes());
    replace_vec.push(type_member_str.as_bytes());
    replace_vec.push(tr.as_bytes());
    replace_vec.push(nav.as_bytes());
    let uid_str: String = uid.to_string();
    replace_vec.push(uid_str.as_bytes());
    let footer_string: String = get_footer();
    replace_vec.push(footer_string.as_bytes());

    let mut tpl_str: HoString = HoFile::read_file_bytes("web/copywrite_list_2.html");
    tpl_str = tpl_str.replace_bytes_vec(src_vec, replace_vec);
    let html: String = tpl_str.to_str().to_string().to_owned();
    res.set_sized_body(Cursor::new(html));
    return res;
}

#[allow(unused_assignments)]
#[get("/copywrite_list?<p>&<topic_type>&<group_id>&<topic_name>", rank = 1)]
fn copywrite_list_4(p: usize, topic_type: String, group_id: usize, topic_name: String, cookies: Cookies, state: State<MySqlDriver>) -> Response<'static> {
    let mut res = Response::new();
    res.set_header(ContentType::HTML);

    // mod_id: String, 
    // mod_menu_open: String, 
    // sub_mod_id: String, 
    // page_title: String, 
    // title: String
    let header: String = get_header(
        "order-mod".to_string(), 
        "order-mod-menu-open".to_string(), 
        "copywrite-order-list".to_string(),
        "用户后台 - 文案订单列表".to_string(), 
        "文案订单列表".to_string(), &cookies,
        &state);

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        res.set_sized_body(Cursor::new("无法建立数据库连接".to_string()));
        return res;
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        res.set_sized_body(Cursor::new("无法获取数据库连接".to_string()));
        return res;
    }

    let mut sql: String = "SELECT `type` FROM `topic` ORDER BY `id` ASC".to_string();
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut type_only_list: Vec<String> = Vec::new();
    let mut type_button_list: String = String::new();
    for row in rows {
        let r: String = from_row::<String>(row);
        let ho_t: HoString = HoString::copy_string(r);
        let type_list: Vec<HoString> = ho_t.split_bytes(",".as_bytes());
        for j in 0..type_list.len() {
            if let Some(type_str) = type_list.get(j) {
                if type_str.compare_str("") {
                    continue;
                } else if type_only_list.contains(&type_str.to_string()) == false {
                    type_only_list.push(type_str.clone().to_string());
                    type_button_list.push_str(
                        format!("<button class=\"dropdown-item\" \
                                type=\"button\" onclick=\"set_type('{}')\">{}</button>", 
                                type_str.to_str(), type_str.to_str()).as_str());
                }
            }
        }
    }

    let mut skip_number: usize = 0;
    sql = format!("SELECT COUNT(`co`.`id`) AS `count` \
                  FROM `copywrite_order` AS `co` \
                  INNER JOIN `topic` AS `t` ON `t`.`id` = `co`.`topic_id` \
                  WHERE `co`.`status` = 0 AND `t`.`type` LIKE '%,{},%' AND `group_id` = 0 \
                  ORDER BY `co`.`id` DESC", topic_type.as_str());
    let rows: Option<Row> = conn.query_first(sql.clone()).unwrap();
    let count: usize;
    if let Some(row) = rows {
        let count_str: String = from_row::<String>(row);
        count = count_str.parse::<usize>().unwrap();
    } else {
        res.set_sized_body(Cursor::new("无法查询订单数量".to_string()));
        return res;
    }
    let max_page: usize = ceil((count / 10) as f64, 0) as usize;
    skip_number = (p - 1) * 10;

    sql = "SELECT `id`, `number` FROM `tag_group`".to_string();
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut type_member_list: Vec<TypeMember> = Vec::new();
    for row in rows {
        let (id_str, number): (String, String) = from_row(row);
        let id: usize = id_str.parse::<usize>().unwrap();
        sql = format!("SELECT COUNT(`id`) AS `count` \
                      FROM `clip_order` \
                      WHERE `group_id` = {} AND \
                            `status` = 4", id.to_string().as_str());
        let row2: Row = conn.query_first(sql.clone()).unwrap().unwrap();
        let count: usize = from_row::<usize>(row2);
        let type_member: TypeMember = TypeMember {
            group_id: id,
            publish_count: count,
            number: number,
            v: Vec::new()
        };
        type_member_list.push(type_member);
    }
    let type_member_count: usize = type_member_list.len();
    for i in 0..type_member_count - 1 {
        for j in 0..type_member_count - i - 1 {
            if type_member_list.get(j).unwrap().publish_count > type_member_list.get(j + 1).unwrap().publish_count {
                type_member_list.swap(j, j + 1);
            }
        }
    }

    for i in 0..type_member_list.len() {
        sql = format!("SELECT `t`.`movie_name` AS `v` \
                      FROM `topic` AS `t` \
                      WHERE `t`.`type` LIKE '%,{},%'", topic_type.as_str());
        let mut topic_list: Vec<String> = Vec::new();
        let topic_rows: Vec<Row> = conn.query(sql.clone()).unwrap();
        for row in topic_rows {
            let v: String = row.get("v").unwrap();
            if topic_list.contains(&v) == false {
                type_member_list[i].v.push(v.clone());
                topic_list.push(v.clone());
            }
        }
    }
    let mut type_member_str: String = String::new();
    for line in type_member_list {
        for v in line.v {
            type_member_str.push_str(format!("<button class=\"dropdown-item\" \
                                             type=\"button\" \
                                             onclick=\"set_topic({}, '{}', '{}')\">{}-{}\
                                             </button>", line.group_id, line.number, v.as_str(), line.number, v.as_str()).as_str());
        }
    }

    sql = format!("SELECT `co`.`id`, `t`.`movie_name` AS `topic_name`, `t`.`bt_file`, `co`.`requirement` FROM `copywrite_order` AS `co` INNER JOIN `topic` AS `t` ON `t`.`id` = `co`.`topic_id` WHERE `co`.`status` = 0 AND `t`.`type` LIKE '%,{},%' AND `t`.`movie_name` = '{}' AND `co`.`group_id` = {} ORDER BY `co`.`id` DESC LIMIT {}, 10", topic_type.as_str(), topic_name.as_str(), group_id, skip_number);
    let table_rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut tr: String = String::new();
    for row in table_rows {
        let (row_id, topic_name, bt_file, requirement): (String, String, String, String) = from_row(row);
        let files: HoString = HoString::copy_string(bt_file);
        let file_list: Vec<HoString> = files.split_bytes(b"|");
        let bt_file: String = file_list.get(0).unwrap().to_string();

        let base_url: &str = state.base_url.as_str();
        tr.push_str(format!("<tr>\
                        <th scope=\"row\">{}</th>\
                        <td>{}</td>\
                        <td>{}</td>\
                        <td><a target=\"_blank\" href=\"{}uploads/bt_file/{}\">下载</a></td>\
                        <td>\
                            <a class=\"btn btn-primary\" target=\"_blank\" href=\"{}copywrite_edit?id={}\">查看</a>\
                            <button class=\"btn btn-success\" onclick=\"get_order({})\">接单</button>\
                        </td>\
                    </tr>", row_id.as_str(), topic_name.as_str(), requirement.as_str(), base_url, bt_file.as_str(), base_url, row_id.as_str(), row_id.as_str()).as_str());
    }

    let mut is_prev_disabled: String = String::new();
    let mut is_next_disabled: String = String::new();
    if p <= 1 {
        is_prev_disabled.push_str(" disabled");
    }
    if p >= max_page {
        is_next_disabled.push_str(" disabled");
    }
    let mut nav: String = format!("<nav>\
                            <ul class=\"pagination justify-content-center\">\
                                <li class=\"page-item{}\">\
                                  <a class=\"page-link\" href=\"copywrite_list.php?p={}&topic_type={}\" aria-label=\"Previous\">\
                                      <span aria-hidden=\"true\">&laquo;</span>\
                                  </a>\
                                </li>", is_prev_disabled.as_str(), (p - 1).to_string().as_str(), topic_type.as_str());
    for i in 1..=max_page {
        if p == i {
            nav.push_str(format!("<li class=\"page-item active\"><a class=\"page-link\" href=\"javascript:void(0);\">{}</a></li>", i).as_str());
        } else {
            nav.push_str(format!("<li class=\"page-item\"><a class=\"page-link\" href=\"copywrite_list.php?p={}&topic_type={}\">{}</a></li>", i, topic_type.as_str(), i).as_str());
        }
    }
    nav.push_str(format!("<li class=\"page-item{}\">\
                            <a class=\"page-link\" href=\"copywrite_list.php?p={}&topic_type={}\" aria-label=\"Next\">\
                                <span aria-hidden=\"true\">&raquo;</span>\
                            </a>\
                          </li>\
                      </ul>\
                    </nav>", is_next_disabled.as_str(), (p + 1).to_string().as_str(), topic_type.as_str()).as_str());

    let mut group_name: String = String::new();
    sql = format!("SELECT `number` AS `v` FROM `tag_group` WHERE `id` = {} LIMIT 1", group_id);
    let group_row: Row = conn.query_first(sql.clone()).unwrap().unwrap();
    let group_number: String = from_row(group_row);
    group_name.push_str(format!("{}-{}", group_number.as_str(), topic_name.as_str()).as_str());

    let mut src_vec: Vec<&[u8]> = Vec::new();
    let mut replace_vec: Vec<&[u8]> = Vec::new();

    let user_info: UserInfo = get_cookies(&cookies);
    let uid: usize = user_info.id;

    src_vec.push("{header}".as_bytes());
    src_vec.push("{base_url}".as_bytes());
    src_vec.push("{skip_number}".as_bytes());
    src_vec.push("{type}".as_bytes());
    src_vec.push("{type_buttons}".as_bytes());
    src_vec.push("{topic_buttons}".as_bytes());
    src_vec.push("{tr}".as_bytes());
    src_vec.push("{nav}".as_bytes());
    src_vec.push("{uid}".as_bytes());
    src_vec.push("{group_name}".as_bytes());
    src_vec.push("{group_id}".as_bytes());
    src_vec.push("{topic_name}".as_bytes());
    src_vec.push("{footer}".as_bytes());
    replace_vec.push(header.as_bytes());
    replace_vec.push(state.base_url.as_bytes());
    let skip_number_str: String = skip_number.to_string();
    replace_vec.push(skip_number_str.as_bytes());
    replace_vec.push(topic_type.as_bytes());
    replace_vec.push(type_button_list.as_bytes());
    replace_vec.push(type_member_str.as_bytes());
    replace_vec.push(tr.as_bytes());
    replace_vec.push(nav.as_bytes());
    let uid_str: String = uid.to_string();
    replace_vec.push(uid_str.as_bytes());
    replace_vec.push(group_name.as_bytes());
    let group_id_str: String = group_id.to_string();
    replace_vec.push(group_id_str.as_bytes());
    replace_vec.push(topic_name.as_bytes());
    let footer_string: String = get_footer();
    replace_vec.push(footer_string.as_bytes());

    let mut tpl_str: HoString = HoFile::read_file_bytes("web/copywrite_list_4.html");
    tpl_str = tpl_str.replace_bytes_vec(src_vec, replace_vec);
    let html: String = tpl_str.to_str().to_string().to_owned();
    res.set_sized_body(Cursor::new(html));
    return res;
}

#[get("/order_history_list?<p>")]
fn order_history_list(p: usize, cookies: Cookies, state: State<MySqlDriver>) -> Response<'static> {
    let mut res = Response::new();
    res.set_header(ContentType::HTML);
    let user_info: UserInfo = get_cookies(&cookies);
    if user_info.id == 0 {
        res.set_sized_body(Cursor::new(format!("您未登录，请先<a href=\"{}login\">登录</a>", state.base_url.as_str())));
        return res;
    }

    // mod_id: String, 
    // mod_menu_open: String, 
    // sub_mod_id: String, 
    // page_title: String, 
    // title: String
    let header: String = get_header(
        "order-mod".to_string(), 
        "order-mod-menu-open".to_string(), 
        "order-history-list".to_string(),
        "用户后台 - 订单历史".to_string(), 
        "订单历史".to_string(), &cookies,
        &state);

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        res.set_sized_body(Cursor::new("无法建立数据库连接".to_string()));
        return res;
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        res.set_sized_body(Cursor::new("无法获取数据库连接".to_string()));
        return res;
    }
    let mut sql: String = format!("SELECT COUNT(`id`) AS `count` FROM `clip_order` WHERE (`status` = 3 OR `status` = 4) AND `get_user_id` = {}", user_info.id);
    let row: Row = conn.query_first(sql.clone()).unwrap().unwrap();
    let count: usize = from_row(row);
    let max_page: usize = ceil((count / 10) as f64, 0) as usize;
    let skip_number: usize = (p - 1) * 10;

    sql = format!("SELECT `clip_o`.`id`, `t`.`movie_name` AS `topic_id`, `t`.`bt_file` FROM `clip_order` AS `clip_o` INNER JOIN `topic` AS `t` ON `t`.`id` = `clip_o`.`topic_id` WHERE (`clip_o`.`status` = 3 OR `clip_o`.`status` = 4) AND `get_user_id` = {} ORDER BY `clip_o`.`id` DESC LIMIT {}, 10", user_info.id, skip_number);
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut bt_file_first: HoString = HoString::new();
    let mut list_html: String = String::new();
    for row in rows {
        let (id, topic_id, bt_file): (usize, String, String) = from_row(row);
        let bt_file_hostr: HoString = HoString::copy_string(bt_file);
        let bt_file_list: Vec<HoString> = bt_file_hostr.split_str("|");
        if let Some(first) = bt_file_list.get(0) {
            bt_file_first = first.clone();
        }
        list_html.push_str(format!("<tr>\
                              <th scope=\"row\">{}</th>\
                              <td>{}</td>\
                              <td><a target=\"_blank\" href=\"{}uploads/bt_file/{}\">下载</a></td>\
                            </tr>", id, topic_id.as_str(), state.base_url.as_str(), bt_file_first.to_str()).as_str());
    }
    let mut is_prev_disabled: String = String::new();
    let mut is_next_disabled: String = String::new();
    if p <= 1 {
        is_prev_disabled.push_str(" disabled");
    }
    if p >= max_page {
        is_next_disabled.push_str(" disabled");
    }
    let mut nav: String = format!("<nav>\
                                    <ul class=\"pagination justify-content-center\">\
                                        <li class=\"page-item{}\">\
                                            <a class=\"page-link\" href=\"order_history_list?p={}\" aria-label=\"Previous\">\
                                                <span aria-hidden=\"true\">&laquo;</span>\
                                            </a>\
                                        </li>", is_prev_disabled.as_str(), p - 1);
    for i in 1..=max_page {
        if p == i {
            nav.push_str(format!("<li class=\"page-item active\"><a class=\"page-link\" href=\"javascript:void(0);\">{}</a></li>", i).as_str());
        } else {
            nav.push_str(format!("<li class=\"page-item\"><a class=\"page-link\" href=\"order_history_list?p={}\">{}</a></li>", i, i).as_str());
        }
    }
    nav.push_str(format!("<li class=\"page-item{}\">\
                            <a class=\"page-link\" href=\"order_history_list?p={}\" aria-label=\"Next\">\
                                <span aria-hidden=\"true\">&raquo;</span>\
                            </a>\
                          </li>\
                      </ul>\
                    </nav>", is_next_disabled.as_str(), p + 1).as_str());

    let mut src_vec: Vec<&[u8]> = Vec::new();
    let mut replace_vec: Vec<&[u8]> = Vec::new();

    let footer_string: String = get_footer();
    src_vec.push("{header}".as_bytes());
    src_vec.push("{base_url}".as_bytes());
    src_vec.push("{list_html}".as_bytes());
    src_vec.push("{nav}".as_bytes());
    src_vec.push("{footer}".as_bytes());
    replace_vec.push(header.as_bytes());
    replace_vec.push(state.base_url.as_bytes());
    replace_vec.push(list_html.as_bytes());
    replace_vec.push(nav.as_bytes());
    replace_vec.push(footer_string.as_bytes());

    let mut tpl_str: HoString = HoFile::read_file_bytes("web/order_history_list.html");
    tpl_str = tpl_str.replace_bytes_vec(src_vec, replace_vec);
    let html: String = tpl_str.to_str().to_string().to_owned();
    res.set_sized_body(Cursor::new(html));
    return res;
}

